package com.heima.comment.service.impl;
import java.math.BigDecimal;

import com.heima.comment.feign.UserFeign;
import com.heima.comment.feign.WemediaFeign;
import com.heima.comment.service.CommentRepayService;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.comment.dtos.WmCommentsDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.comment.pojos.ApCommentRepayLike;
import com.heima.model.comment.vo.ApCommentRepayInWmVo;
import com.heima.model.comment.vo.ApCommentRepayVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.media.pojos.WmUser;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @作者 itcast
 * @创建日期 2021/2/21 14:15
 **/
@Service
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    UserFeign userFeign;
    @Autowired
    private WemediaFeign wemediaFeign;
    @Override
    public ResponseResult WmSaveCommentRepay(CommentRepaySaveDto dto) {
        ApUser user = AppThreadLocalUtils.getUser();
        if(user==null||user.getId()==null)
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        WmUser wmUser = wemediaFeign.findWmUserById(Long.valueOf(user.getId()));
        if (wmUser==null)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        user.setId(wmUser.getApUserId());
        AppThreadLocalUtils.setUser(user);
        return saveCommentRepay(dto);
    }

    @Override
    public ResponseResult loadCommentRepayForWm(CommentRepayDto dto) {
        // 1. 检查参数 (评论ID   最小时间)
        //    size=20
        if(dto == null || dto.getCommentId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getMinDate() == null){
            dto.setMinDate(new Date());
        }
        int size = 20;
        // 2. 查询评论回复列表
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate()))
                .with(Sort.by(Sort.Direction.DESC,"createdTime"))
                .limit(size);
        // 查询到的评论回复列表
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);
        //封装结果
        List<ApCommentRepayInWmVo> apCommentRepayInWmVos = apCommentRepays.stream().map(apCommentRepay -> {
            ApCommentRepayInWmVo apCommentRepayInWmVo = new ApCommentRepayInWmVo();
            apCommentRepayInWmVo.setContent(apCommentRepay.getContent());
            apCommentRepayInWmVo.setNickName(apCommentRepay.getAuthorName());
            return apCommentRepayInWmVo;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(apCommentRepayInWmVos);
    }

    @Override
    public List<ApCommentRepay> findCommentRepayByCommentId(String commentId) {
        Query query = Query.query(Criteria.where("commentId").is(commentId));
        return mongoTemplate.find(query,ApCommentRepay.class);
    }

    @Override
    public ResponseResult loadCommentRepay(CommentRepayDto dto) {
        // 1. 检查参数 (评论ID   最小时间)
        //    size=20
        if(dto == null || dto.getCommentId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getMinDate() == null){
            dto.setMinDate(new Date());
        }
        int size = 20;
        // 2. 查询评论回复列表
        //    （commentId = 评论id  and createTime < minDate  order by createTime desc limit 20）
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate()))
                            .with(Sort.by(Sort.Direction.DESC,"createdTime"))
                            .limit(size);
        // 查询到的评论回复列表
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);
        // 3. 判断当前用户是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        // 3.1 如果未登录直接返回评论回复列表
        if(user == null || user.getId() == null){
            return ResponseResult.okResult(apCommentRepays);
        }
        // 3.2 如果登录，判断当前回复列表中，哪些回复我们点过赞
        //  根据当前的回复列表通过流获取ID列表
        List<String> repayIdList = apCommentRepays.stream().map(ApCommentRepay::getId).collect(Collectors.toList());
        //  查询当前回复列表中  我们给哪些回复点赞过
        if(apCommentRepays == null || apCommentRepays.isEmpty()){
            return ResponseResult.okResult(apCommentRepays);
        }
        Query findRepayLikeQuery = Query.query(Criteria.where("commentRepayId").in(repayIdList).and("authorId").is(user.getId()));
        //  当前回复列表  相关我们的点赞信息
        List<ApCommentRepayLike> apCommentRepayLikes = mongoTemplate.find(findRepayLikeQuery, ApCommentRepayLike.class);
        // 我们点赞过的回复ID
        Set<String> commentRepayIds = apCommentRepayLikes.stream().map(ApCommentRepayLike::getCommentRepayId).collect(Collectors.toSet());
        List<ApCommentRepayVo> repayVoList = apCommentRepays.stream().map(repay -> {
            ApCommentRepayVo repayVo = new ApCommentRepayVo();
            BeanUtils.copyProperties(repay, repayVo);

            if (commentRepayIds.contains(repay.getId())) {
                repayVo.setOperation((short) 0);
            }
            return repayVo;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(repayVoList);
    }
    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDto dto) {
        // 1. 检查参数  （ 评论ID   回复内容  是否登录 ）
        if(dto == null || dto.getCommentId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if(dto.getContent() ==null || dto.getContent().length()>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if(user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN,"需要登录后才能回复");
        }
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if(apComment == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"要回复的评论不存在");
        }
        // 2. 远程获取登录用户信息
        ApUser userInfo = userFeign.findUserById(Long.valueOf(user.getId()));
        // 3. 阿里云检测回复内容
        // 4. 保存评论回复信息
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(userInfo.getId());
        apCommentRepay.setAuthorName(userInfo.getName());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setLikes(0);
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());
        mongoTemplate.save(apCommentRepay);
        // 5. 更新评论回复数量 +1
        apComment.setReply(apComment.getReply()+1);
        mongoTemplate.save(apComment);
        return ResponseResult.okResult();
    }
    @Override
    public ResponseResult saveCommentRepayLike(CommentRepayLikeDto dto) {
        // 1. 检查参数 (回复ID  operation ： 0 或 1    是否登录)
        if(dto == null || dto.getCommentRepayId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if(dto.getOperation() == null || (dto.getOperation()!=0 && dto.getOperation() !=1)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if(user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 2. 根据回复ID查询回复数据
        ApCommentRepay commentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
        if(commentRepay == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 3. 根据点赞方式 进行对应的处理
        if(dto.getOperation() == 0){
            // 3.1 如果为0 代表点赞
            // 回复数据的点赞数+1
            commentRepay.setLikes(commentRepay.getLikes() + 1);
            mongoTemplate.save(commentRepay);
            // 保存当前点赞信息
            ApCommentRepayLike commentRepayLike = new ApCommentRepayLike();
            commentRepayLike.setAuthorId(user.getId());
            commentRepayLike.setCommentRepayId(dto.getCommentRepayId());
            commentRepayLike.setOperation((short)0);
            mongoTemplate.save(commentRepayLike);
        }else {
            // 3.2 如果为1 代表取消点赞
            // 回复数据的点赞数-1
            commentRepay.setLikes(commentRepay.getLikes()==0? 0 : commentRepay.getLikes() - 1);
            mongoTemplate.save(commentRepay);
            // 删除点赞信息
            Query query = Query.query(Criteria.where("commentRepayId").is(dto.getCommentRepayId()).and("authorId").is(user.getId()));
            mongoTemplate.remove(query,ApCommentRepayLike.class);
        }
        // 4. 返回赞的总数量
        Map map = new HashMap<>();
        map.put("likes",commentRepay.getLikes());
        return ResponseResult.okResult(map);
    }
}
